/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-02-27     liyih       the first version
 */
#ifndef APPLICATIONS_AD9910_AD9910_BASE_H_
#define APPLICATIONS_AD9910_AD9910_BASE_H_

#include <drivers/pin.h>
#include <memory>
#include <board.h>
#include <rtdevice.h>
#include "drv_spi.h"
#include <vector>

class AD9910_Base
{
public:
    //* PIN definitions
    static constexpr rt_base_t PIN_PWR = GET_PIN(E, 0);      // 掉电控制脚。数字输入。置高(3.3V)芯片关机，不使用需接地。
    /*static constexpr rt_base_t PIN_SDIO = GET_PIN(E, 1);*/ // 串行数据输入/输出。
    static constexpr rt_base_t PIN_DPH = GET_PIN(E, 3);      // 数字斜坡保持。数字输入。置高(3.3V)有效,不使用需接地。
    static constexpr rt_base_t PIN_DRO = GET_PIN(E, 5);      // 数字斜坡结束。数字输出(高电平有效)
    static constexpr rt_base_t PIN_IOUP = GET_PIN(C, 13);    // 同步信号(LVDS),数字输入(上升沿有效)。写完多个寄存器后给一个高脉冲。
    static constexpr rt_base_t PIN_PF0 = GET_PIN(F, 0);      // Profile_0选择引脚。数字输入（高电平有效）。
    static constexpr rt_base_t PIN_PF1 = GET_PIN(F, 1);      // Profile_1选择引脚。数字输入（高电平有效）。
    static constexpr rt_base_t PIN_PF2 = GET_PIN(F, 2);      // Profile_2选择引脚。数字输入（高电平有效）。
    static constexpr rt_base_t PIN_RST = GET_PIN(E, 2);      // 主机复位，数字输入（高电平有效）。
    /*static constexpr rt_base_t PIN_SCK = GET_PIN(E, 6);*/  // 串行数据时钟。数字时钟(上升沿执行写操作，下降沿执行读操作)
    static constexpr rt_base_t PIN_DRC = GET_PIN(E, 4);      // 数字斜坡控制。数字输入.控制数字斜坡发生器的斜率极性,不使用需接地。
    static constexpr rt_base_t PIN_OSK = GET_PIN(F, 4);      // 输出振幅键控。数字输入。
    static constexpr rt_base_t PIN_CSB = GET_PIN(F, 3);      // 数字输入。SPI通信CS控制脚及通信复位脚。

    //* Registers address
    static constexpr uint8_t WRITE_REG = 0x00;
    static constexpr uint8_t READ_REG = 0x80;

    static constexpr uint8_t REG_CFR1 = 0x00;
    static constexpr uint8_t REG_CFR2 = 0x01;
    static constexpr uint8_t REG_CFR3 = 0x02;
    static constexpr uint8_t REG_AUX_DAC_CTRL = 0x03;
    static constexpr uint8_t REG_IO_UPDATE_RATE = 0x04;
    static constexpr uint8_t REG_FTW = 0x07;
    static constexpr uint8_t REG_POW = 0x08;
    static constexpr uint8_t REG_ASF = 0x09;
    static constexpr uint8_t REG_MULT_CHIP_SYNC = 0x0A;
    static constexpr uint8_t REG_DRG_LIMIT = 0x0B;
    static constexpr uint8_t REG_DRG_STEP = 0x0C;
    static constexpr uint8_t REG_DRG_RATE = 0x0D;
    static constexpr uint8_t REG_PROFILE_0 = 0x0E;
    static constexpr uint8_t REG_PROFILE_1 = 0x0F;
    static constexpr uint8_t REG_PROFILE_2 = 0x10;
    static constexpr uint8_t REG_PROFILE_3 = 0x11;
    static constexpr uint8_t REG_PROFILE_4 = 0x12;
    static constexpr uint8_t REG_PROFILE_5 = 0x13;
    static constexpr uint8_t REG_PROFILE_6 = 0x14;
    static constexpr uint8_t REG_PROFILE_7 = 0x15;
    static constexpr uint8_t REG_RAM = 0x16;

    std::vector<uint8_t> CFR1;
    std::vector<uint8_t> CFR2;
    std::vector<uint8_t> CFR3;

    AD9910_Base();
    virtual ~AD9910_Base();

    void IO_config();
    static void IO_update();
    void IO_reset();
    void module_reset();
    void module_init();
    void power_reset();

    virtual void setDefaultCFR();

    rt_err_t spi_sendData(const uint8_t reg, const std::vector<uint8_t> &data);
    rt_err_t spi_sendRam(const std::vector<uint32_t> &data);
    rt_err_t spi_readRam(std::vector<uint32_t> &data);

private:
    rt_spi_device *spi_dev;
};

#endif /* APPLICATIONS_AD9910_AD9910_BASE_H_ */
